
using System.Collections.Generic;
using System.Dynamic;
using System.IO;
using System.IO.Enumeration;
using System.Linq;
using System.Runtime;
using System.Threading.Tasks;
using Godot;
using Godot.Collections;
using Godot.NativeInterop;
using Ink.Runtime;
using Microsoft.VisualBasic;

class SaveAndLoadManager
{

    // 存储数据分为三个文件：数据文件，配置文件，截图png，其中数据文件仅仅保存数据,配置文件保存存储名称以及其他显示信息 
    //数据文件后缀为.save，命名为时间戳命名
    //配置文件后缀为.saveCfg,命名为时间戳命名 (不做定义名称)

    public static SaveAndLoadManager _instance;

    private const string savePath = "user://gameSave";  //文件名称为 文件名#时间戳

    private const string saveSuffix = ".save";

    private const string saveCfgName = "saveConfig.saveCfg";  //暂不启用

    private System.Collections.Generic.Dictionary<string, string> tempDict = new System.Collections.Generic.Dictionary<string, string>();  //自定义名称，时间戳
    public static SaveAndLoadManager getInstance()
    {
        if (_instance == null)
        {
            _instance = new SaveAndLoadManager();
        }
        return _instance;
    }

    private List<string> _saveItemList = new List<string>();  //显示名称列表

    public List<string> SaveItemList
    {

        get
        {
            if (_saveItemList.Count == 0)
            {
                if (Godot.DirAccess.DirExistsAbsolute(savePath))
                {
                    //没有数据的时候第一次处理，其他情况在save时候已经保存数据
                    var fileList = Godot.DirAccess.GetFilesAt(savePath + "/");
                    if (fileList.Length > 0)
                    {
                        foreach (var file in fileList)
                        {
                            /*if (file==saveCfgName)
                            {
                                var saveGameCfg = Godot.FileAccess.Open(savePath + "/" + file, Godot.FileAccess.ModeFlags.Read);
                                if (Godot.FileAccess.GetOpenError() == Error.Ok)
                                {

                                }
                                tempDict.Add(file.Substr(file.IndexOf("("), file.IndexOf(")") - file.IndexOf("(")), file.Substr(0, file.IndexOf("(") - 1));
                            }*/
                            tempDict.Add(file.Substr(0, file.IndexOf(".")), file.Substr(0, file.IndexOf(".")));
                        }

                        GD.Print(tempDict);
                        _saveItemList = tempDict.OrderBy(kv => kv.Value).Select(kv => kv.Key).ToList();

                        _saveItemList.Reverse();  //倒叙排列*/

                    }
                }


            }
            return _saveItemList;
        }
    }

    /*public string GetSaveFileName(string name)
    {
        return tempDict[name] + "(" + name + ")";
    }*/

    public async Task Save(string name = null)  //指定名称
    {

        string time = TimeUtil.GetNowTImeString();
        string fileName = time;

        // string picName = null;
        // if (name != null)
        // {
        //     fileName = time + "(" + name + ")";
        //     picName = name;
        // }
        // else
        // {
        //     fileName = time + "(" + name + ")"; ;
        //     picName = time;
        // }
        CatpurePicManager.getInstance().SaveCaptureScreenShot(fileName);
        var type = Godot.FileAccess.ModeFlags.Write;



        if (!Godot.DirAccess.DirExistsAbsolute(savePath))
        {
            //目录不存在创建目录
            var err = DirAccess.MakeDirAbsolute(savePath);
            GD.Print(err);


        }


        // var saveGameConfig = Godot.FileAccess.Open(savePath + "/"+saveCfgName, Godot.FileAccess.ModeFlags.WriteRead);
        // if (Godot.FileAccess.GetOpenError() == Error.Ok)
        // {
        //     Godot.Collections.Dictionary<string, Variant> cfgDatas = new Godot.Collections.Dictionary<string, Variant>();
        //     Godot.Collections.Dictionary<string, Variant> fileData = new Godot.Collections.Dictionary<string, Variant>();
        //     if (name == null)
        //     {
        //         fileData.Add("customName", fileName);
        //     }
        //     else
        //     {
        //         fileData.Add("customName", name);
        //     }
        //     var text = saveGameConfig.GetAsText();
        //     cfgDatas.Add(fileName, fileData);
        //     var jsonString = Godot.Json.Stringify(cfgDatas);
        //     text = text + "/n" + jsonString;
        //     saveGameConfig.StoreLine(text);
        //     saveGameConfig.Close();
        // }


        var saveGame = Godot.FileAccess.Open(savePath + "/" + fileName + saveSuffix, type);

        if (Godot.FileAccess.GetOpenError() == Error.Ok)
        {

            Godot.Collections.Dictionary<string, Variant> datas = new Godot.Collections.Dictionary<string, Variant>();

            //组装数据操作
            var actorData = ActorModel.getInstance().GetSaveData();
            var sceneData = SceneUtil.currentScene.GetSaveData();
            datas.Add("time", time);
            datas.Add("actorData", actorData);
            datas.Add("sceneData", sceneData);

            var nameData = new Godot.Collections.Dictionary<string, Variant>();
            nameData.Add(fileName, datas);
            var jsonString = Godot.Json.Stringify(nameData);

            saveGame.StoreLine(jsonString);
            //添加数据用于显示
            _saveItemList.Add(fileName);

            saveGame.Close();



        }
        else
        {
            GD.Print("读取失败");

        }
        await Task.Delay(2000);
        EventManager.getInstance().dispatchEvent(EventType.EVENT_FINISH_SAVE);
    }


    public void Load(int index = 0)
    {
        if (SaveItemList.Count > index)
        {
            var fileName = tempDict[SaveItemList[index]];
            if (!Godot.FileAccess.FileExists(savePath + "/" + fileName + saveSuffix))
            {
                GD.Print("文件不存在");
                return;
            };
            var saveGame = Godot.FileAccess.Open(savePath + "/" + fileName + saveSuffix, Godot.FileAccess.ModeFlags.Read);
            if (Godot.FileAccess.GetOpenError() == Error.Ok)
            {

                while (saveGame.GetPosition() < saveGame.GetLength())
                {
                    var json = new Godot.Json();
                    var result = json.Parse(saveGame.GetLine());
                    if (result == Error.Ok)
                    {
                        var subData = new Godot.Collections.Dictionary<string, Variant>((Godot.Collections.Dictionary)json.Data);

                        if (subData.ContainsKey(fileName))
                        {
                            var allData = new Godot.Collections.Dictionary<string, Variant>((Godot.Collections.Dictionary)subData[fileName]);
                            //GD.Print("读取数据！！！！！", ((Godot.Collections.Dictionary)allData["actorData"])["Hp"]);

                            //加载数据操作
                            ActorModel.getInstance().Load((Godot.Collections.Dictionary<string, Variant>)allData["actorData"]);
                            SceneUtil.currentScene.Load((Godot.Collections.Dictionary<string, Variant>)allData["sceneData"]);
                        }
                    }


                }
            }

            //GD.Print(Godot.Json.ParseString(saveGame.GetLine()));

        }



    }

    public void DeleteSaveDataByName(string name)  //入参为显示名称
    {

        var fileName = tempDict[name];
        if (Godot.FileAccess.FileExists(savePath + "/" + fileName + saveSuffix))
        {
            Godot.DirAccess.RemoveAbsolute(savePath + "/" + fileName + saveSuffix);
            //Godot.DirAccess.RemoveAbsolute(savePath + "/" + fileName + saveCfgSuffix);
            //删除保存图片
            _saveItemList.Remove(name);
            tempDict.Remove(name);
            CatpurePicManager.getInstance().DeletePngFromName(fileName);
        }


    }

    public void ClearSaveData()
    {
        DirAccess.RemoveAbsolute(savePath);
        CatpurePicManager.getInstance().ClearAllPng();
    }

    public ImageTexture GetScreenShotByName(string name)
    { //显示名称
        var fileName = tempDict[name];
        return CatpurePicManager.getInstance().GetImageFromShotPath(fileName);
    }



}
